/*
@author: ZZH
@date: 2021-11-05
@time: 14:21:39
@info: 红黑树实现函数模板文件
*/
#pragma once
#include "RB-Tree-Base.h"

#define RBT_WEAK __attribute__((weak))

//声明全部实现函数和数据结构的宏
#define RBT_IMP_REF(keyType, valueType, suffix) typedef struct\
{\
    RBTreeNode_t pointer;\
    keyType key;\
    valueType value;\
}RBTree_##suffix##_t, * pRBTree_##suffix##_t;\
\
RBT_WEAK pRBTree_t RBT_Create_##suffix(void);\
RBT_WEAK void RBT_CreateStatic_##suffix(pRBTree_t tree);\
RBT_WEAK uint8_t RBT_Insert_##suffix(pRBTree_t tree, keyType key, valueType value);\
RBT_WEAK uint8_t RBT_DeleteNodeByKey_##suffix(pRBTree_t tree, keyType key);\
RBT_WEAK uint8_t RBT_DeleteNode_##suffix(pRBTree_t tree, pRBTree_##suffix##_t node);\
RBT_WEAK valueType RBT_Search_##suffix(pRBTree_t tree, keyType key, RBT_CompareResult_t cond, uint8_t* res);\
RBT_WEAK pRBTree_##suffix##_t RBT_Search_##suffix##Node(pRBTree_t tree, keyType key, RBT_CompareResult_t cond);\
RBT_WEAK keyType RBT_Next_##suffix(pRBTree_t tree, keyType key, uint8_t* res);\
RBT_WEAK pRBTree_##suffix##_t RBT_Next_##suffix##Node(pRBTree_##suffix##_t node);\
RBT_WEAK void RBT_Delete_##suffix(pRBTree_t tree);

//定义全部实现函数的宏
#define RBT_IMP_DEF(keyType, valueType, suffix) RBT_WEAK RBT_CompareResult_t RBT_Compare_##keyType(pRBTreeNode_t node, void* key)\
{\
    keyType keyNode = container_of(node, RBTree_##suffix##_t, pointer)->key;\
    keyType keyCmp = *(keyType*) key;\
\
    if (keyNode == keyCmp)\
        return RBT_Equal;\
    else if (keyNode < keyCmp)\
        return RBT_Big;\
    else\
        return RBT_Small;\
}\
\
RBT_WEAK void RBT_Copy_##suffix(pRBTreeNode_t node1, pRBTreeNode_t node2)\
{\
    pRBTree_##suffix##_t node1C = container_of(node1, RBTree_##suffix##_t, pointer);\
    pRBTree_##suffix##_t node2C = container_of(node2, RBTree_##suffix##_t, pointer);\
\
    node1C->key = node2C->key;\
    node1C->value = node2C->value;\
}\
\
RBT_WEAK void RBT_Free_##suffix(void* node)\
{\
    Free(container_of(node, RBTree_##suffix##_t, pointer));\
}\
\
RBT_WEAK pRBTree_t RBT_Create_##suffix(void)\
{\
    pRBTree_t tree = Malloc(sizeof(RBTree_t));\
    RBT_CreateStatic_##suffix(tree);\
    return tree;\
}\
\
RBT_WEAK void RBT_CreateStatic_##suffix(pRBTree_t tree)\
{\
    __RBT_CreateStatic(tree);\
    tree->compare = RBT_Compare_##keyType;\
    tree->copy = RBT_Copy_##suffix;\
    tree->free = RBT_Free_##suffix;\
}\
\
RBT_WEAK uint8_t RBT_Insert_##suffix(pRBTree_t tree, keyType key, valueType value)\
{\
    pRBTree_##suffix##_t node = Malloc(sizeof(RBTree_##suffix##_t));\
\
    if (node == NULL)\
        return 0;\
\
    node->key = key;\
    node->value = value;\
\
    uint8_t res = __RBT_InsertNode(tree, &node->pointer, &node->key);\
\
    if (res == 0)\
        Free(node);\
\
    return res;\
}\
\
RBT_WEAK uint8_t RBT_DeleteNodeByKey_##suffix(pRBTree_t tree, keyType key)\
{\
    return RBT_DeleteNode_##suffix(tree, RBT_Search_##suffix##Node(tree, key, RBT_Equal));\
}\
\
RBT_WEAK uint8_t RBT_DeleteNode_##suffix(pRBTree_t tree, pRBTree_##suffix##_t node)\
{\
    if (node == NULL)\
        return 0;\
\
    return __RBT_DeleteNode(tree, &node->pointer);\
}\
\
RBT_WEAK valueType RBT_Search_##suffix(pRBTree_t tree, keyType key, RBT_CompareResult_t cond, uint8_t* res)\
{\
    pRBTree_##suffix##_t node = RBT_Search_##suffix##Node(tree, key, cond);\
    uint8_t isNodeVaild = node != NULL;\
\
    if (res)\
        *res = isNodeVaild;\
\
    return isNodeVaild ? node->value : (valueType)0;\
}\
\
RBT_WEAK pRBTree_##suffix##_t RBT_Search_##suffix##Node(pRBTree_t tree, keyType key, RBT_CompareResult_t cond)\
{\
    pRBTreeNode_t node = __RBT_SearchNodeCond(tree, &key, cond);\
    return container_of(node, RBTree_##suffix##_t, pointer);\
}\
\
RBT_WEAK keyType RBT_Next_##suffix(pRBTree_t tree, keyType key, uint8_t* res)\
{\
    pRBTree_##suffix##_t node = RBT_Next_##suffix##Node(RBT_Search_##suffix##Node(tree, key, RBT_Equal));\
    uint8_t isNodeVaild = node != NULL;\
\
    if (res)\
        *res = isNodeVaild;\
\
    return isNodeVaild ? node->key : 0;\
}\
\
RBT_WEAK pRBTree_##suffix##_t RBT_Next_##suffix##Node(pRBTree_##suffix##_t node)\
{\
    pRBTreeNode_t nodeNext = __RBT_Next(&node->pointer);\
    return (node == NULL) ? NULL : container_of(nodeNext, RBTree_##suffix##_t, pointer);\
}\
\
RBT_WEAK void RBT_Delete_##suffix(pRBTree_t tree)\
{\
    RBT_Clear(tree);\
    Free(tree);\
}


